#!/usr/bin/env python 

import os.path

class ErrException(Exception):
	def __init__(self, value):
		self.value = value
	def __str__(self):
		return repr(self.value)


class  NewErr(object):
	_mgaic 	= 0
	_name  	= str()
	_cap   	= 0
	_errors = list()

	def __init__(self,magic,name):
		self._magic = magic
		self._name   = name

	def setCap(self,cap):
		self._cap = cap

	def define(self,name,msg):
		self._errors.append(tuple([name,msg]))


	def gen(self,path,filename):
		cFile = os.path.join(path,filename+".c")
		hFile = os.path.join(path,filename+".h")

		try:
			cfd   = open(cFile,'wb')
			hfd = open(hFile,'wb')
		except:
			print "Open filr %s,%s error" %(cFile,hFile)
			return None

		try:
			cSource =  self.genCSource()
			hSource =  self.genHSource()
		except ErrException as e:
			print "Gen source error "
			print e
			return None

		cfd.write(cSource)
		hfd.write(hSource)

		cfd.close()
		hfd.close()


	def genHSource(self):
		baseStr = """
/**
* Gen by gen_errno 
* Please don't modify
*/

#ifndef _%(NAME)s_ERRORNO_H
#define _%(NAME)s_ERRORNO_H

#include <sys/types.h>

typedef int32_t code_t;

/**
* Three base class code
*/

#define _%(NAME)s_MAGIC_CODE    %(magic)d
#define _%(NAME)s_MAX_CODE      (_%(NAME)s_MAGIC_CODE + %(cap)d)

""" % {"NAME":self._name.upper(),"magic":self._magic,"cap":self._cap}

		for i,err in enumerate(self._errors) :
			if i+1 > self._cap:
				raise ErrException("error code is so many! Change your capacity first!")   
			errStr = "#define %s     (-%d)     // %s \n" % (err[0],i+self._magic+1,err[1])
			baseStr += errStr

	
		baseStr +="""
char *%(name)s_strerror(code_t code);
#endif
"""	% {"name":self._name.lower()}

		return baseStr

	def genCSource(self):
		baseStr= """
/**
* Gen by gen_errno 
* Please don't modify
*/
#include "errno.h"

static char *_errstrs_[] = {
"""
		for err in self._errors:
			errmsg = '\t\t"%s", \n' % (err[1])
			baseStr += errmsg
		baseStr += """
	};

char *%(name)s_strerror(code_t code)
{
	if (code >=0 || (-code) > _%(NAME)s_MAX_CODE){
		return "Bad error code!";	
	}
	code = -code;
	int i = code - _%(NAME)s_MAGIC_CODE;
	return _errstrs_[i];

}
""" % {"name":self._name.lower(),"NAME":self._name.upper()}

		return baseStr


